package com.dingyx.ps.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dingyx.ps.mapper.GoodsListMapper;
import com.dingyx.ps.mapper.MemberListMapper;
import com.dingyx.ps.mapper.PostListMapper;
import com.dingyx.ps.mapper.ReceiveRecordMapper;
import com.dingyx.ps.model.PageEntity;
import com.dingyx.ps.model.ReturnT;
import com.dingyx.ps.model.entity.*;
import com.dingyx.ps.model.po.GoodsListPO;
import com.dingyx.ps.model.po.GoodsPO;
import com.dingyx.ps.model.po.LocationPO;
import com.dingyx.ps.model.po.MemberUpdatePO;
import com.dingyx.ps.model.vo.GoodsListVO;
import com.dingyx.ps.model.vo.GoodsVO;
import com.dingyx.ps.model.vo.PostListVO;
import com.dingyx.ps.model.vo.ReceiveRecordVO;
import com.dingyx.ps.task.PSOrderCreateService;
import com.dingyx.ps.task.PSOrderVendoutService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Slf4j
@Api(description="小程序端接口")
@RestController
@RequestMapping(value = "/app")
public class AppController {
    @Resource
    private PostListMapper postListMapper;
    @Resource
    private GoodsListMapper goodsListMapper;
    @Resource
    private MemberListMapper memberListMapper;
    @Resource
    private ReceiveRecordMapper receiveRecordMapper;
    @Autowired
    private PSOrderCreateService psOrderCreateService;
    @Autowired
    private PSOrderVendoutService psOrderVendoutService;

    @ApiOperation(value = "【小程序】 首页", response = PostListVO.class)
    @PostMapping("/homePage")
    public ReturnT homePage(@RequestBody @Validated LocationPO param) {
        log.info("用户位置-->{}", JSONObject.toJSONString(param));
        Page<PostListDTO> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<PostListDTO> pages = postListMapper.selectPageList(page);
        List<PostListVO> pageList = new ArrayList<>();
        for(PostListDTO dto : pages.getRecords()){
            PostListVO vo = new PostListVO();
            BeanUtils.copyProperties(dto, vo);
            //创建GeodeticCalculator，调用计算方法，传入坐标系、经纬度用于计算距离
            GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(
                    Ellipsoid.Sphere,
                    new GlobalCoordinates(dto.getPostLatitude(), dto.getPostLongitude()),
                    new GlobalCoordinates(param.getLatitude(), param.getLongitude())
            );
            vo.setDistance2Me(geoCurve.getEllipsoidalDistance());
            pageList.add(vo);
        }
        if(CollectionUtil.isNotEmpty(pageList)){
            pageList.sort(Comparator.comparing(PostListVO::getDistance2Me));
            pageList.get(0).setClosest2Me(0);
        }
        return ReturnT.SUCCESS(pageList);
    }

    @ApiOperation(value = "【小程序】 商品列表", response = GoodsVO.class)
    @PostMapping("/goodsPage")
    public ReturnT goodsPage(@RequestBody PageEntity param) {
        log.info("查询商品信息-->{}", JSONObject.toJSONString(param));
        Page<GoodsListDTO> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<GoodsListDTO> pages = goodsListMapper.selectPageList(page);
        return ReturnT.SUCCESS(pages);
    }

    @ApiOperation(value = "【小程序】 商品剩余数量", response = GoodsVO.class)
    @PostMapping("/remainingQuantity")
    public ReturnT remainingQuantity(@RequestBody @Validated GoodsPO param) {
        log.info("查询商品信息-->{}", JSONObject.toJSONString(param));
//        QueryWrapper<GoodsListDTO> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("goods_id", 1);
//        GoodsListDTO userDTO = goodsListMapper.selectOne(queryWrapper);
        return ReturnT.SUCCESS(3);
    }

    @ApiOperation(value = "【小程序】 领取商品")
    @PostMapping("/receiveGoods")
    public ReturnT receiveGoods(@RequestBody @Validated GoodsPO param) {
        log.info("查询商品信息-->{}", JSONObject.toJSONString(param));
        String skuId = param.getGoodsNum();
        // 查询商品
        GoodsListDTO goodsDTO = goodsListMapper.findByGoodsNum(skuId);
        if(Objects.isNull(goodsDTO)){
            return ReturnT.ERROR("商品不存在");
        }
        // 验证商品领取规则
        QueryWrapper<ReceiveRecordDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("goods_num", param.getGoodsNum());
        queryWrapper.eq("member_id", param.getMemberId());
        List<ReceiveRecordDTO> receiveRecordDTOS = receiveRecordMapper.selectList(queryWrapper);
        if(CollectionUtil.isNotEmpty(receiveRecordDTOS) && goodsDTO.getRuleClaimTimes() <= receiveRecordDTOS.size()){

        }
        List<Map<String, String>> skus = new ArrayList<>();
        Map<String, String> sku = new HashMap<>();
        sku.put(param.getGoodsNum(), "1");
        skus.add(sku);
        String startDay = DateUtil.today();
        String endDay = DateUtil.today();
        String orderCreateResult = psOrderCreateService.openApiMethod(param.getPostNum(), skus, startDay, endDay);
        JSONObject ocResult = JSONObject.parseObject(orderCreateResult);
        if(!"SUCCESS".equalsIgnoreCase(ocResult.getString("return_code"))){
            // todo 新增领取记录
            ReceiveRecordDTO dto = new ReceiveRecordDTO();
            receiveRecordMapper.insert(dto);
            return ReturnT.ERROR(ocResult.getString("return_desc"));
        }
        String orderSeq = ocResult.getString("order_seq");
        String orderVendoutResult = psOrderVendoutService.openApiMethod(orderSeq);
        JSONObject ovResult = JSONObject.parseObject(orderVendoutResult);
        if(!"SUCCESS".equalsIgnoreCase(ovResult.getString("return_code"))){
            // todo 新增领取记录
            ReceiveRecordDTO dto = new ReceiveRecordDTO();
            receiveRecordMapper.insert(dto);
            return ReturnT.ERROR(ocResult.getString("return_desc"));
        }
        return ReturnT.SUCCESS(0);
    }

    @ApiOperation(value = "【小程序】 领取记录", response = ReceiveRecordVO.class)
    @PostMapping("/receiveRecord")
    public ReturnT receiveRecord(@RequestBody @Validated PageEntity param) {
        log.info("receiveRecord-->{}", JSONObject.toJSONString(param));
        Page<ReceiveRecordDTO> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<ReceiveRecordDTO> pages = receiveRecordMapper.selectPageList(page);
        return ReturnT.SUCCESS(pages);
    }

    @ApiOperation(value = "【小程序】 补全手机号用户名", response = GoodsListVO.class)
    @PostMapping("/updateInfo")
    public ReturnT updateInfo(@RequestBody @Validated MemberUpdatePO param) {
        log.info("receiveRecord-->{}", JSONObject.toJSONString(param));
        MemberListDTO dto = new MemberListDTO();
        BeanUtils.copyProperties(param, dto);
        int result = memberListMapper.updateById(dto);
        return ReturnT.SUCCESS(result);
    }

    @ApiOperation(value = "接受通知", response = GoodsListVO.class)
    @PostMapping("/notifyUrl")
    public ReturnT notifyUrl(HttpServletRequest request, HttpServletResponse response) throws IOException {
        InputStream inStream;
        inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        log.info("refund:接受通知----start----");
        // 获取微信调用我们notify_url的返回信息
        String result = new String(outSteam.toByteArray(), "utf-8");
        log.info("refund:接受通知----result----=" + result);
        // 关闭流
        outSteam.close();
        inStream.close();
        return ReturnT.SUCCESS();
    }

}